package com.xdf.xzymanagementsystem.service.impl;

import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.xdf.xzymanagementsystem.dao.HalfDetailMapper;
import com.xdf.xzymanagementsystem.dao.HalfMainMapper;
import com.xdf.xzymanagementsystem.dao.OrderMainMapper;
import com.xdf.xzymanagementsystem.dao.ProductMainMapper;
import com.xdf.xzymanagementsystem.entity.*;
import com.xdf.xzymanagementsystem.service.HalfMainService;
import com.xdf.xzymanagementsystem.util.CodeGenUtil;
import com.xdf.xzymanagementsystem.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description : 服务层实现类，由代码生成器自动生成
 * @Author : chanchaw
 * @Date : 2025-3-21 18:43:41
 */
@Slf4j
@Service
public class HalfMainServiceImpl extends ServiceImpl<HalfMainMapper, HalfMain> implements HalfMainService {
    @Autowired
    private HalfMainMapper dao;
    @Autowired
    private HalfDetailMapper halfDetailMapper;
    @Autowired
    private SystemUtils systemUtils;
    @Autowired
    private CodeGenUtil codeGenUtil;
    @Autowired
    private OrderMainMapper orderMainMapper;
    @Autowired
    private ProductMainMapper productMainMapper;
    //=================以上是自动生成的代码，自定义代码请写在下面==================
    @Override
    public List<Map<String, Object>> selectAllDTO(Date sdate, Date edate, int flag) {
        return dao.selectAllDTO(sdate, edate, flag);
    }

    //新增单据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public HalfMainDTO insertDTO(HalfMainDTO record) throws Exception {
//        if (selectRepeatOrderNo(record.getOrderNo()) != null) throw new RuntimeException("订单号已存在,不允许重复！！");
        List<HalfDetail> detailList = record.getDetailList();
        if (record.getBillType().equals("色布退坯布商") ||
                record.getBillType().equals("本厂退深加工2") ||
                record.getBillType().equals("本厂退染厂") ||
                record.getBillType().equals("本厂退深加工1")) {
            List<Map<String, Object>> list = productMainMapper.selectInventory(record.getOrderNo());//该订单号下，当前的库存
            compareKiloValues(list, detailList);//判断是否超出库存数量
        }
        HalfMain halfMain = new HalfMain();
        BeanUtils.copyProperties(record, halfMain);
        halfMain.setCreateUser(systemUtils.getLoginUsername());
        halfMain.setState(1);
        halfMain.setBillCode(getBillCode());
        dao.insertSelective(halfMain);//新增主表数据
        for (HalfDetail halfDetail : detailList) {
            halfDetail.setParentId(halfMain.getId());//关联主表id
            halfDetail.setState(1);
            halfDetail.setCreateUser(systemUtils.getLoginUsername());
            halfDetailMapper.insertSelective(halfDetail);
        }
        //获取数据并返回
        HalfMainDTO halfMainDTO = selectDTO(halfMain.getId());
        return halfMainDTO;
    }

    public static void compareKiloValues(List<Map<String, Object>> list, List<HalfDetail> detailList) {
        for (Map<String, Object> map : list) {
            String halfName = (String) map.get("productName");
            String halfSpecification = (String) map.get("productSpecification");
            String color = (String) map.get("color");
            BigDecimal listKilo = BigDecimal.ZERO;
            if (!Optional.ofNullable(map.get("kilo")).orElse("").equals("")) listKilo = new BigDecimal(map.get("kilo").toString());
            for (HalfDetail detail : detailList) {
                if (halfName.equals(detail.getHalfName()) &&
                        halfSpecification.equals(detail.getHalfSpecification()) &&
                        color.equals(detail.getColor())) {
                    BigDecimal detailKilo = detail.getKilo();
                    if (listKilo.compareTo(detailKilo) < 0) throw new RuntimeException("退回的数量超出库存！！");
                }
            }
        }
    }

    //检测订单号是否重复
    private HalfMain selectRepeatOrderNo(String orderNo) {
        return dao.selectRepeatOrderNo(orderNo);
    }

    //生成单据编号
    private String getBillCode() {
        HalfMain halfMain = dao.selectMaxBillCode();
        int year = LocalDate.now().getYear();
        int monthValue = LocalDate.now().getMonthValue();
        int day = LocalDate.now().getDayOfMonth();
        if (halfMain != null) {
            String billCode = halfMain.getBillCode();
            int codeNumber = Integer.parseInt(billCode.substring(8));
            int dayNumber = Integer.parseInt(billCode.substring(6, 8));
            if (dayNumber != day) {
                codeNumber = 0;
            }
            return "HF" + String.valueOf(year).substring(2) + String.format("%02d", monthValue) + String.format("%02d", day)  + String.format("%03d", codeNumber + 1);
        }else {
            return "HF" + String.valueOf(year).substring(2) + String.format("%02d", monthValue) + String.format("%02d", day)  + String.format("%03d", 1);
        }
    }

    @Override
    public HalfMainDTO selectDTO(Integer id) {
        HalfMainDTO halfMainDTO = new HalfMainDTO();
        HalfMain main = dao.selectById(id);//查询主表
        List<HalfDetail> details = halfDetailMapper.selectByParentId(id);
        BeanUtils.copyProperties(main, halfMainDTO);
        halfMainDTO.setDetailList(details);
        return halfMainDTO;
    }

    //修改单据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public HalfMainDTO updateDTO(HalfMainDTO record) {
//        GreyMain main = selectRepeatOrderNo(record.getOrderNo());
        //订单号相同，id不同
//        if (main != null) {
//            if (main.getOrderNo().equals(record.getOrderNo()) && !main.getId().equals(record.getId())) throw new RuntimeException("订单号已存在,不允许重复！！");
//        }
        List<HalfDetail> detailList = record.getDetailList();
        if (record.getBillType().equals("色布退坯布商") ||
                record.getBillType().equals("本厂退深加工2") ||
                record.getBillType().equals("本厂退染厂") ||
                record.getBillType().equals("本厂退深加工1")) {
            List<Map<String, Object>> list = productMainMapper.selectInventory(record.getOrderNo());//该订单号下，当前的库存
            compareKiloValues(list, detailList);//判断是否超出库存数量
        }
        HalfMain halfMain = new HalfMain();
        BeanUtils.copyProperties(record, halfMain);
        halfMain.setUpdateTime(new Date());
        halfMain.setUpdateUser(systemUtils.getLoginUsername());
        if (dao.update(halfMain) < 0) throw new RuntimeException("修改主表时发生错误！");
        for (HalfDetail halfDetail : detailList) {
            if (Optional.ofNullable(halfDetail.getId()).orElse(0) == 0) {
                halfDetail.setParentId(halfMain.getId());//关联主表id
                halfDetail.setState(1);
                halfDetail.setCreateUser(systemUtils.getLoginUsername());
                halfDetailMapper.insertSelective(halfDetail);
            }
            halfDetail.setUpdateTime(new Date());
            halfDetail.setUpdateUser(systemUtils.getLoginUsername());
            if (halfDetailMapper.update(halfDetail) < 0) throw new RuntimeException("修改明细时发生错误！");
        }
        List<HalfDetail> details = halfDetailMapper.selectByParentId(record.getId());
        //删除掉删除行的明细
        List<HalfDetail> extraDetails = getDeleteDetails(detailList, details);
        if (extraDetails.size() > 0) {
            for (HalfDetail extraDetail : extraDetails) {
                halfDetailMapper.deleteById(extraDetail.getId());
            }
        }
        return selectDTO(record.getId());
    }

    //查询过滤删除行的明细
    private static List<HalfDetail> getDeleteDetails(List<HalfDetail> detailList, List<HalfDetail> details) {
        // 提取detailList中所有元素的ID集合
        Set<Integer> detailIds = detailList.stream()
                .map(HalfDetail::getId)
                .collect(Collectors.toSet());
        // 过滤出details中ID不在detailIds的元素
        List<HalfDetail> extraDetails = details.stream()
                .filter(d -> !detailIds.contains(d.getId()))
                .collect(Collectors.toList());
        return extraDetails;
    }

    //批量删除
    @Override
    public void deleteByIds(List<Integer> ids) {
        for (Integer id : ids) {
            HalfMain halfMain = dao.selectById(id);
            OrderMain orderMain = orderMainMapper.selectRepeatOrderNo(halfMain.getOrderNo());
            if (orderMain.getState() == 2) throw new RuntimeException("该订单已完成，不允许删除！！");
            List<HalfDetail> details = halfDetailMapper.selectByParentId(id);
            if (details.size() > 0) {
                for (HalfDetail detail : details) {
                    detail.setIsDelete(1);
                    detail.setUpdateUser(systemUtils.getLoginUsername());
                    detail.setUpdateTime(new Date());
                    halfDetailMapper.update(detail);
                }
            }
            halfMain.setIsDelete(1);
            halfMain.setUpdateUser(systemUtils.getLoginUsername());
            halfMain.setUpdateTime(new Date());
            dao.update(halfMain);
        }
    }
}